package com.yunchao.bank.main.data.repository

import android.content.Context
import android.util.LruCache
import com.yunchao.bank.main.data.dao.DispatchTaskDao
import com.yunchao.bank.main.data.model.DispatchTaskEntity
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.File
import java.io.FileOutputStream

class DispatchTaskDatasource(
    private val context: Context,
    private val dispatchTaskDao: DispatchTaskDao,
    private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) {

    // 在线任务缓存（最大缓存5个任务，每个任务最大1MB）
    private val onlineTaskCache = object : LruCache<Int, String>(5 * 1024 * 1024) {
        override fun sizeOf(key: Int, value: String): Int {
            return value.toByteArray().size
        }
    }

    // 获取离线任务存储目录
    private val offlineTaskDir: File by lazy {
        File(context.filesDir, DispatchTaskEntity.OFFLINE_TASK_DIR).apply {
            if (!exists()) mkdirs()
        }
    }

    /**
     * 保存任务数据
     * @param taskId 任务ID
     * @param data 任务数据（可能很大）
     * @param isOffline 是否为离线任务
     */
    suspend fun saveTask(
        taskId: Int,
        data: String,
        isOffline: Boolean,
        timestamp: Long
    ): Boolean {
        return try {
            if (isOffline) {
                saveOfflineTask(taskId, data, timestamp)
            } else {
                saveOnlineTask(taskId, data, timestamp)
            }
            true
        } catch (e: Exception) {
            false
        }
    }


    /**
     * 获取任务数据
     */
    suspend fun getTaskData(taskId: Int): Pair<DispatchTaskEntity, String?>? {
        // 先查询数据库获取任务基本信息
        val taskEntity = dispatchTaskDao.getByTaskId(taskId) ?: return null

        return if (taskEntity.isOffline) {
            // 离线任务：从文件读取数据
            taskEntity.dataPath?.let { path ->
                taskEntity to File(path).takeIf { it.exists() }?.readText()
            }
        } else {
            // 在线任务：从缓存获取数据
            taskEntity to onlineTaskCache[taskId]
        }
    }

    /**
     * 获取下一个待处理的任务数据
     */
    suspend fun getNextPendingTask(): Pair<DispatchTaskEntity, String?>? {
        // 先查询数据库下一个待处理的任务
        val taskEntity = dispatchTaskDao.getNextPendingTask() ?: return null

        return if (taskEntity.isOffline) {
            // 离线任务：从文件读取数据
            taskEntity.dataPath?.let { path ->
                taskEntity to File(path).takeIf { it.exists() }?.readText()
            }
        } else {
            // 在线任务：从缓存获取数据
            taskEntity.taskId.let { taskId ->
                taskEntity to onlineTaskCache[taskId]
            }
        }
    }


    /**
    * 更新任务状态并返回更新后的任务及数据
    * @param id 任务ID
    * @param status 新状态
    * @return Pair of updated DispatchTaskEntity and task data (if available), or null if task not found
    */
    suspend fun updateTaskStatusAndGetTask(id: Int, status: Int): Pair<DispatchTaskEntity, String?>? {
        return dispatchTaskDao.getByTaskId(id)?.let { task ->
            // 更新任务状态
            val updatedTask = task.copy( status = status)
            dispatchTaskDao.update(updatedTask)

            // 获取任务数据
            val data = if (updatedTask.isOffline) {
                updatedTask.dataPath?.let { path ->
                    File(path).takeIf { it.exists() }?.readText()
                }
            } else {
                onlineTaskCache[updatedTask.taskId]
            }

            updatedTask to data
        }
    }


    /**
     * 删除任务（包括数据和记录）
     */
    suspend fun deleteTask(taskId: Int) {
        // 先获取任务信息
        val taskEntity = dispatchTaskDao.getByTaskId(taskId) ?: return

        if (taskEntity.isOffline) {
            // 删除离线任务文件
            taskEntity.dataPath?.let { path ->
                File(path).takeIf { it.exists() }?.delete()
            }
        } else {
            // 从缓存移除在线任务
            onlineTaskCache.remove(taskId)
        }

        // 删除数据库记录
        dispatchTaskDao.deleteByTaskId(taskId)
    }

    /**
     * 清理所有离线任务文件
     */
    fun cleanupOfflineFiles() {
        offlineTaskDir.listFiles()?.forEach { it.delete() }
    }

    /**
     * 保存离线任务（数据存储到文件，路径存入数据库）
     */
    private suspend fun saveOfflineTask(taskId: Int, data: String, timestamp: Long) =
        withContext(ioDispatcher) {
            // 创建任务文件
            val taskFile = File(offlineTaskDir, "task_$taskId.dat")

            // 写入数据到文件
            FileOutputStream(taskFile).use { fos ->
                fos.write(data.toByteArray())
                fos.fd.sync() // 强制写入磁盘
            }

            // 创建数据库记录
            val taskEntity = DispatchTaskEntity(
                taskId = taskId,
                isOffline = true,
                timestamp = timestamp,
                dataPath = taskFile.absolutePath
            )
            dispatchTaskDao.insert(taskEntity)
        }

    /**
     * 保存在线任务（数据存入缓存）
     */
    private suspend fun saveOnlineTask(taskId: Int, data: String, timestamp: Long) {
        // 存入缓存
        onlineTaskCache.put(taskId, data)

        // 创建数据库记录（dataPath为null）
        val taskEntity = DispatchTaskEntity(
            taskId = taskId,
            isOffline = false,
            dataPath = null, status = 0,
            timestamp = timestamp
        )
        dispatchTaskDao.insert(taskEntity)
    }



}